/* This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as 
 * published by the Free Software Foundation
 */

#include <libintl.h>
#include <locale.h>
#include <libgen.h>

#define _(a) gettext(a)

#include <stdio.h>
#include <stdlib.h>
#include <objbase.h>

#define COBJMACROS 1
#define __RPC__deref_out

#include "GoogleDesktopApi.h"
#include "GoogleDesktopApi_i.c"

const BSTR clsid = L"{10A51BCE-6670-65DA-F0C0-40A8060C107F}";

BSTR ansi2bstr(const char *str);
IGoogleDesktopRegistrar *registrar_get(void);
int plugin_register(void);
int plugin_unregister(void);
void rusage(char *argv0);
void rerror(char *argv0, const char *msg);

BSTR
ansi2bstr(const char *str) {
    OLECHAR *tmp;
    BSTR bstr;
    int chars;

    chars = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, NULL, 0);
    tmp = (OLECHAR*) malloc(chars * sizeof (OLECHAR));

    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, str, -1, tmp, chars);

    bstr = SysAllocString(tmp);
    free(tmp);

    return bstr;
}

IGoogleDesktopRegistrar *
registrar_get(void) {
    IGoogleDesktopRegistrar *reg;
    HRESULT hr;

    hr = CoCreateInstance(&CLSID_GoogleDesktopRegistrar, NULL, CLSCTX_SERVER,
            &IID_IGoogleDesktopRegistrar, (void **) & reg);

    return reg;
}

int
plugin_register(void) {
    IGoogleDesktopRegistrar *reg;
    IGoogleDesktopRegisterIndexingPlugin *ireg;
    HRESULT hr;

    SAFEARRAYBOUND bound;
    SAFEARRAY *args;
    long index;

    VARIANT vargs;
    VARIANT title,
            description,
            icon;
    VARIANT rtitle,
            rdescription,
            ricon;

    reg = registrar_get();

    bound.lLbound = 0;
    bound.cElements = 6;

    args = SafeArrayCreate(VT_VARIANT, 1, &bound);

    if (!args) return -1;

    V_VT(&title) = V_VT(&rtitle) = VT_BSTR;
    V_BSTR(&title) = SysAllocString(L"Title");
    V_BSTR(&rtitle) = SysAllocString(L"PidginDS");

    index = 0;
    SafeArrayPutElement(args, &index, &title);
    index = 1;
    SafeArrayPutElement(args, &index, &rtitle);

    V_VT(&description) = V_VT(&rdescription) = VT_BSTR;
    V_BSTR(&description) = SysAllocString(L"Description");
    V_BSTR(&rdescription) = ansi2bstr(_("Google Desktop Plugin for Pidgin"));

    index = 2;
    SafeArrayPutElement(args, &index, &description);
    index = 3;
    SafeArrayPutElement(args, &index, &rdescription);

    V_VT(&icon) = V_VT(&ricon) = VT_BSTR;
    V_BSTR(&icon) = SysAllocString(L"Icon");
    V_BSTR(&ricon) = SysAllocString(L"C:\\Program Files\\Pidgin\\pidgin.exe,0");

    index = 4;
    SafeArrayPutElement(args, &index, &icon);
    index = 5;
    SafeArrayPutElement(args, &index, &ricon);

    V_VT(&vargs) = VT_ARRAY | VT_VARIANT;
    V_ARRAY(&vargs) = args;

    hr = IGoogleDesktopRegistrar_StartComponentRegistration(reg, clsid, vargs);
    hr = IGoogleDesktopRegistrar_GetRegistrationInterface(reg,
            L"GoogleDesktop.IndexingRegistration", (IUnknown **) & ireg);

    hr = IGoogleDesktopRegisterIndexingPlugin_RegisterIndexingPlugin(ireg, NULL);
    hr = IGoogleDesktopRegistrar_FinishComponentRegistration(reg);

    SafeArrayDestroy(args);

    if (FAILED(hr)) return -1;

    IGoogleDesktopRegisterIndexingPlugin_Release(ireg);
    IGoogleDesktopRegistrar_Release(reg);

    return 0;
}

int
plugin_unregister(void) {
    IGoogleDesktopRegistrar *reg;
    HRESULT hr;

    reg = registrar_get();

    hr = IGoogleDesktopRegistrar_UnregisterComponent(reg, clsid);
    IGoogleDesktopRegistrar_Release(reg);

    return FAILED(hr);
}

void
rusage(char *argv0) {
    fprintf(stderr, _("Usage: %s (-i|u)\n"), basename(argv0));
    exit(-1);
}

void
rerror(char *argv0, const char *msg) {
    fprintf(stderr, _("ERROR (%s): %s\n"), basename(argv0), msg);
    exit(-1);
}

int main(int argc, char *argv[]) {
    HRESULT hr;
    char *locale;

    locale = dirname(argv[0]);

    setlocale(LC_ALL, "");
    bindtextdomain("register", locale);
    textdomain("register");

    hr = CoInitialize(NULL);

    if (FAILED(hr)) rerror(argv[0], "CoInitialize");

    if (argc != 2) rusage(argv[0]);

    if (!strcmp(argv[1], "-i")) {
        if (plugin_register())
            rerror(argv[0], _("error on registering"));
    } else if (!strcmp(argv[1], "-u")) {
        if (plugin_unregister())
            rerror(argv[0], _("error on unregistering"));
    } else rusage(argv[0]);

    return 0;
}
